

from PIL import Image
# import sys
from prettytable import PrettyTable
from sklearn import svm
from sklearn.cluster import DBSCAN
from sklearn.ensemble import IsolationForest
from sklearn.neighbors import LocalOutlierFactor
from streamlit_extras.colored_header import colored_header
from streamlit_option_menu import option_menu

from business.algorithm.utils import *



with st.sidebar:
    sub_option = option_menu(None, ["数据可视化", "异常值检测"])
if  sub_option == "数据可视化":
    colored_header(label="数据可视化", description=" ", color_name="violet-90")
    file = st.file_uploader("Upload `.csv` file", type=['csv'], label_visibility="collapsed")
    if file is None:
        table = PrettyTable(['file name', 'class', 'description'])
        table.add_row(['file_1', 'dataset', 'data file'])
        st.write(table)
    if file is not None:
        df = pd.read_csv(file)

        check_string_NaN(df)

        colored_header(label="数据信息", description=" ", color_name="violet-70")

        nrow = st.slider("行数", 1, len(df), 5)
        df_nrow = df.head(nrow)
        st.write(df_nrow)

        colored_header(label="数据统计", description=" ", color_name="violet-30")

        st.write(df.describe())

        tmp_download_link = download_button(df.describe(), f'statistics.csv', button_text='download')

        st.markdown(tmp_download_link, unsafe_allow_html=True)

        colored_header(label="特征&目标", description=" ", color_name="violet-70")

        target_num = st.number_input('目标数量', min_value=1, max_value=10, value=1)
        col_feature, col_target = st.columns(2)
        # features
        features = df.iloc[:, :-target_num]
        # targets
        targets = df.iloc[:, -target_num:]
        with col_feature:
            st.write(features.head())
        with col_target:
            st.write(targets.head())

        colored_header(label="特征分布", description=" ", color_name="violet-30")
        feature_selected_name = st.selectbox('特征', list(features), 1)
        feature_selected_value = features[feature_selected_name]
        plot = customPlot()
        col1, col2 = st.columns([1, 3])
        with col1:
            with st.expander("绘图参数"):
                options_selected = [plot.set_title_fontsize(18), plot.set_label_fontsize(19),
                                    plot.set_tick_fontsize(20), plot.set_legend_fontsize(21),
                                    plot.set_color('柱颜色', 0, 22)]
        with col2:
            plot.feature_distribution(options_selected, feature_selected_name, feature_selected_value)

        with col1:
            with st.expander("绘图参数"):
                options_selected = [plot.set_title_fontsize(1), plot.set_label_fontsize(2),
                                    plot.set_tick_fontsize(3), plot.set_legend_fontsize(4),
                                    plot.set_color('line color', 6, 5), plot.set_color('柱颜色', 0, 6)]
        with col2:
            plot.feature_hist_kde(options_selected, feature_selected_name, feature_selected_value)

        # =========== Targets visulization ==================

        colored_header(label="目标分布", description=" ", color_name="violet-30")

        target_selected_name = st.selectbox('target', list(targets))

        target_selected_value = targets[target_selected_name]
        plot = customPlot()
        col1, col2 = st.columns([1, 3])
        with col1:
            with st.expander("绘图参数"):
                options_selected = [plot.set_title_fontsize(7), plot.set_label_fontsize(8),
                                    plot.set_tick_fontsize(9), plot.set_legend_fontsize(10),
                                    plot.set_color('line color', 6, 11), plot.set_color('柱颜色', 0, 12)]
        with col2:
            plot.target_hist_kde(options_selected, target_selected_name, target_selected_value)

        # =========== Features analysis ==================

        colored_header(label="特征分析", description=" ", color_name="violet-30")

        feature_range_selected_name = st.slider('特征数量', 1, len(features.columns), (1, 2))
        min_feature_selected = feature_range_selected_name[0] - 1
        max_feature_selected = feature_range_selected_name[1]
        feature_range_selected_value = features.iloc[:, min_feature_selected: max_feature_selected]
        data_by_feature_type = df.groupby(list(feature_range_selected_value))
        feature_type_data = create_data_with_group_and_counts(data_by_feature_type)
        IDs = [str(id_) for id_ in feature_type_data['ID']]
        Counts = feature_type_data['Count']
        col1, col2 = st.columns([1, 3])
        with col1:
            with st.expander("绘图参数"):
                options_selected = [plot.set_title_fontsize(13), plot.set_label_fontsize(14),
                                    plot.set_tick_fontsize(15), plot.set_legend_fontsize(16),
                                    plot.set_color('柱颜色', 0, 17)]
        with col2:
            plot.featureSets_statistics_hist(options_selected, IDs, Counts)
    st.write('---')

elif sub_option == "异常值检测":
    colored_header(label="异常值检测", description=" ", color_name="violet-90")
    file = st.file_uploader("Upload `.csv` file", type=['csv'], label_visibility="collapsed")
    if file is None:
        table = PrettyTable(['file name', 'class', 'description'])
        table.add_row(['file_1', 'dataset', 'data file'])
        st.write(table)
    if file is not None:
        df = pd.read_csv(file)
        check_string_NaN(df)
        colored_header(label="数据信息", description=" ", color_name="violet-70")
        nrow = st.slider("rows", 1, len(df), 5)
        df_nrow = df.head(nrow)
        st.write(df_nrow)

        colored_header(label="特征&目标", description=" ", color_name="violet-70")

        target_num = st.number_input('目标数量', min_value=1, max_value=10, value=1)

        col_feature, col_target = st.columns(2)

        features = df.iloc[:, :-target_num]

        targets = df.iloc[:, -target_num:]
        with col_feature:
            st.write(features.head())
        with col_target:
            st.write(targets.head())

        # colored_header(label="target", description=" ", color_name="violet-70")

        # target_selected_option = st.selectbox('target', list(targets)[::-1])

        # target = targets[target_selected_option]

        colored_header(label="异常值检测", description=" ", color_name="violet-30")

        model_path = './models/outlier detection'

        template_alg = model_platform(model_path)

        inputs, col2 = template_alg.show()

        if inputs['model'] == 'One Class SVM':

            detector = svm.OneClassSVM(nu=inputs['nu'], kernel='rbf', gamma=inputs['gamma'])
            detector.fit(features)
            outlier = detector.predict(features)
            normal = df[outlier == 1]
            abnormal = df[outlier == -1]
            st.write('------------------ 正常 --------------------')
            st.write(normal)
            tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

            st.write('------------------ 异常 --------------------')
            st.write(abnormal)
            tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

        elif inputs['model'] == 'IsolationForest':

            detector = IsolationForest(n_estimators=inputs['n_estimators'], contamination=inputs['contamination'],
                                       random_state=inputs['random state'])
            detector.fit(features)
            outlier = detector.predict(features)

            normal = df[outlier == 1]
            abnormal = df[outlier == -1]
            st.write('------------------ 正常 --------------------')
            st.write(normal)
            tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

            st.write('------------------ 异常 --------------------')
            st.write(abnormal)
            tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

        elif inputs['model'] == 'DBSCAN':

            model = DBSCAN()
            model.fit(features)
            outlier = model.labels_
            normal = df[outlier == 1]
            abnormal = df[outlier == -1]
            st.write('------------------ 正常 --------------------')

            st.write(normal)
            tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

            st.write('------------------ 异常 --------------------')
            st.write(abnormal)
            tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

        elif inputs['model'] == 'LocalOutlierFactor':

            detector = LocalOutlierFactor(n_neighbors=20, contamination=0.1)
            outlier = detector.fit_predict(features)

            normal = df[outlier == 1]
            abnormal = df[outlier == -1]
            st.write('------------------ 正常 --------------------')
            st.write(normal)
            tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

            st.write('------------------ 异常 --------------------')
            st.write(abnormal)
            tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)
